#include "addface.h"
#include "ui_addface.h"
#include <QDebug>

using namespace cv;
using namespace std;

extern CascadeClassifier cascade;

AddFace::AddFace(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::AddFace)
{
    ui->setupUi(this);

    this->pRegister = new Register;

    connect(ui->back,&QPushButton::clicked,[=](){
        emit this->back();
    });

    //连接compare信号和槽函数
    connect(this,SIGNAL(compare()),this,SLOT(compare_face()));

    //连接子窗口send信号和父窗口槽函数，用于传递数据
    connect(this->pRegister,SIGNAL(send(QString, QString, QString, QString, QString)),this,SLOT(add_face(QString, QString, QString, QString, QString)));
}

AddFace::~AddFace()
{
    delete ui;
}

void AddFace::on_begin_clicked()
{
    //调用摄像头
    VideoCapture video;
    video.open(0);

    //
    stop = false;
    int sig = 0;
    std::chrono::steady_clock::time_point startTime;

    //检测摄像头是否成功打开
    if (!video.isOpened()) {
    qDebug() << "摄像头加载出错！";
    exit(-1);
    }

    /*载入已训练的人脸识别算法，具体路径需要根据opencv库安装位置在config.h更改*/
    const string casPath = HAAR_PATH;

    //检测是否成功加载级联分类器
    if (!cascade.load(casPath)) {
        qDebug() << "算法加载失败！";
        exit(-1);
    }


    while (stop != true) {
        Mat vClip;
        video >> vClip;  //视频转为图像

        //若突然没有视频信号则结束
        if (vClip.empty()) {
            break;
        }

        //灰度化，减少计算
        Mat imgGray;
        cvtColor(vClip, imgGray, COLOR_BGR2GRAY);

        vector<Rect> faces(0);
        cascade.detectMultiScale(imgGray, faces, 1.1, 2, 0, Size(30, 30));  //调用人脸识别算法

        if (faces.size() > 0) {
            for (size_t i = 0; i < faces.size(); i++) {
                rectangle(vClip, faces[i], Scalar(0, 0, 255), 2, 8, 0);  //生成矩形框出人脸
            }
        }

        //未检测到人脸
        if (faces.size() == 0) {
            ui->info->setText("未识别到人脸！");
            sig = 0;
        }

        //不止一张人脸（不能确定谁录入）
        else if (faces.size() > 1) {
            ui->info->setText("请逐个录入！");
            sig = 0;
        }

        //只有一张人脸
        else {
            ui->info->setText("请保持不动！");
            sig++;

            //检测到只有一张人脸3秒后进行比对，其间一旦出现不是一张人脸的情况，将重新计时
            if (sig == 1) {
                startTime = chrono::steady_clock::now();
            }

            if (sig >= 3) {
                chrono::steady_clock::time_point currentTime = chrono::steady_clock::now();
                chrono::duration<double> interval = currentTime - startTime;

                if (interval.count() >= 3.0 ) {
                    emit compare();  //发送compare信号进行比对，compare肯定要带参数
                    break;
                }

            }

        }

        //转换图片格式以输出
        Mat temp;
        cvtColor(vClip,temp,COLOR_BGR2RGB);
        QImage Qtemp = QImage((const unsigned char*)(temp.data),
                                temp.cols, temp.rows, temp.step,
                                QImage::Format_RGB888);

        ui->detect->setPixmap(QPixmap::fromImage(Qtemp));  //输出检测后带框的人脸

        waitKey(1); //waitkey 1ms的延迟
        QApplication::processEvents();
    }
}

//compare信号的槽函数，在这里本质上其实是函数调用
void AddFace::compare_face(){

    ui->info->setText("识别成功！");
    //如果库中已有人脸，显示提示框
    //if..... QMessagebox...


    //如果库中没有人脸，则跳转到新窗口进行注册
    //else...
    this->pRegister->show();

}

//send信号槽函数，接收并处理身份信息和人脸数据
void AddFace::add_face(QString a, QString b, QString c, QString d, QString e){
    //生成新的人脸信息
    //包括输入的五个身份信息和人脸特征 new...
    qDebug()<<a;
    qDebug()<<b;
    qDebug()<<c;
    qDebug()<<d;
    qDebug()<<e;  //在这里先用qDebug直观显示
}



//停止按钮，停止检测，清屏
void AddFace::on_stop_clicked()
{
    stop = true;
    ui->info->clear();
    ui->detect->clear();
}

//返回按钮，停止检测，清屏并返回上一界面
void AddFace::on_back_clicked()
{
    stop = true;
    ui->info->clear();
    ui->detect->clear();
}

